/*
 * Copyright (c) 2016. For Intelligent Group.
 */

package com.intelligent.ispc.core.service.impl;

import com.google.common.collect.Lists;
import com.intelligent.ispc.common.mapper.JsonMapper;
import com.intelligent.ispc.common.utils.ApplicationException;
import com.intelligent.ispc.common.utils.ExceptionMessages;
import com.intelligent.ispc.common.utils.ResourceBundleUtils;
import com.intelligent.ispc.common.utils.StringUtils;
import com.intelligent.ispc.constant.AppConstant;
import com.intelligent.ispc.core.dto.GrrConfigDto;
import com.intelligent.ispc.core.dto.GrrItemDto;
import com.intelligent.ispc.core.dto.SpcConfigDto;
import com.intelligent.ispc.core.dto.SystemConfigDto;
import com.intelligent.ispc.core.entity.GrrConfig;
import com.intelligent.ispc.core.entity.GrrItem;
import com.intelligent.ispc.core.entity.SpcConfig;
import com.intelligent.ispc.core.repository.GrrConfigDao;
import com.intelligent.ispc.core.repository.GrrItemDao;
import com.intelligent.ispc.core.repository.SpcConfigDao;
import com.intelligent.ispc.core.service.SystemService;
import com.intelligent.ispc.utils.SystemConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * Created by Julia.Zhou on 2016/07/12.
 */
@Service
public class SystemServiceImpl implements SystemService {

    private final Logger logger = LoggerFactory.getLogger(SystemServiceImpl.class);

    @Autowired
    private GrrConfigDao grrConfigDao;

    @Autowired
    private SpcConfigDao spcConfigDao;

    @Autowired
    private GrrItemDao grrItemDao;

    @Autowired
    private SystemConfig systemConfig;

    private JsonMapper mapper = new JsonMapper();


    @Override
    public List<String> getGrrKeys() {
        List<String> keys = Lists.newArrayList();
        List<String> searchKeys = mapper.fromJson(systemConfig.getSearchKeys(), List.class);
        List<String> attributeKeys = mapper.fromJson(systemConfig.getAttributeKeys(), List.class);
        if (searchKeys != null && !searchKeys.isEmpty()) {
            keys.addAll(searchKeys);
        }
        if (attributeKeys != null && !attributeKeys.isEmpty()) {
            keys.addAll(attributeKeys);
        }
        return keys;
    }

    @Override
    public SystemConfigDto findSystemConfig() {
        SystemConfigDto systemConfigDto = new SystemConfigDto();
        List<String> searchKeyDtos = mapper.fromJson(systemConfig.getSearchKeys(), List.class);
        List<String> attributeKeys = mapper.fromJson(systemConfig.getAttributeKeys(), List.class);
        List<String> yieldValidateKey = mapper.fromJson(systemConfig.getYieldValidateKey(), List.class);

        systemConfigDto.setSearchKeyKeys(searchKeyDtos);
        systemConfigDto.setAttributeKeys(attributeKeys);
        if (yieldValidateKey != null && !yieldValidateKey.isEmpty() && yieldValidateKey.size() == 2) {
            systemConfigDto.setYieldValidateKey(yieldValidateKey.get(0));
            systemConfigDto.setYieldValidatePassValue(yieldValidateKey.get(1));
        }
        systemConfigDto.setPrimaryKey(systemConfig.getPrimaryKey());
        systemConfigDto.setGrrExportNumber(systemConfig.getGrrExportNumber());
        systemConfigDto.setSpcExportNumber(systemConfig.getSpcExportNumber());
        return systemConfigDto;
    }

    @Override
    public void createOrUpdateGrrConfig(GrrConfigDto grrConfigDto) {
        if (grrConfigDto == null) {
            throw new ApplicationException(ExceptionMessages.ERR_14001, ResourceBundleUtils.getString(ExceptionMessages.EXCEPTION_CONFIG_PARAMETER_INVALID));
        }
        GrrConfig grrConfig = grrConfigDao.findGrrConfig();
        if (grrConfig == null) {
            grrConfig = new GrrConfig();
            BeanUtils.copyProperties(grrConfigDto, grrConfig);
            grrConfigDao.createGrrConfig(grrConfig);
        } else {
            grrConfigDto.setId(grrConfig.getId());
            BeanUtils.copyProperties(grrConfigDto, grrConfig);
            grrConfigDao.updateGrrConfig(grrConfig);

        }
    }

    @Override
    public void createGrrConfig(GrrConfigDto grrConfigDto) {
        if (grrConfigDto == null) {
            throw new ApplicationException(ExceptionMessages.ERR_14001, ResourceBundleUtils.getString(ExceptionMessages.EXCEPTION_CONFIG_PARAMETER_INVALID));
        }
        GrrConfig grrConfig = new GrrConfig();
        BeanUtils.copyProperties(grrConfigDto, grrConfig);
        grrConfigDao.createGrrConfig(grrConfig);
    }

    @Override
    public void updateGrrConfig(GrrConfigDto grrConfigDto) {
        if (grrConfigDto == null || grrConfigDto.getId() == null) {
            throw new ApplicationException(ExceptionMessages.ERR_14001, ResourceBundleUtils.getString(ExceptionMessages.EXCEPTION_CONFIG_PARAMETER_INVALID));
        }
        GrrConfig grrConfig = grrConfigDao.findById(grrConfigDto.getId());
        if (grrConfig == null) {
            throw new ApplicationException(ExceptionMessages.ERR_15007, ResourceBundleUtils.getString(ExceptionMessages.EXCEPTION_GLOBAL_OBJECT_INVALID));
        }
        grrConfigDto.setId(grrConfig.getId());
        BeanUtils.copyProperties(grrConfigDto, grrConfig);
        grrConfigDao.updateGrrConfig(grrConfig);
    }

    @Override
    public GrrConfigDto findGrrConfig() {
        GrrConfig grrConfig = grrConfigDao.findGrrConfig();
        if (grrConfig == null) {
            throw new ApplicationException(ExceptionMessages.ERR_15007, ResourceBundleUtils.getString(ExceptionMessages.EXCEPTION_GLOBAL_OBJECT_INVALID));
        }

        GrrConfigDto dto = new GrrConfigDto();
        BeanUtils.copyProperties(grrConfig, dto);
        return dto;
    }

    @Override
    public void createGrrItem(GrrItemDto grrItemDto) {
        if (grrItemDto == null) {
            throw new ApplicationException(ExceptionMessages.ERR_14001, ResourceBundleUtils.getString(ExceptionMessages.EXCEPTION_CONFIG_PARAMETER_INVALID));
        }

        GrrItem grrItem = new GrrItem();
        BeanUtils.copyProperties(grrItemDto, grrItem);
        grrItemDao.createGrrItem(grrItem);
    }

    @Override
    public void updateGrrItem(GrrItemDto grrItemDto) {
        if (grrItemDto == null || (grrItemDto.getId() == null && StringUtils.isBlank(grrItemDto.getGrrName()))) {
            throw new ApplicationException(ExceptionMessages.EXCEPTION_PARAMETER_INPUT_INVALID);
        }
        GrrItem grrItem = null;
        if (grrItemDto.getId() != null) {
            grrItem = grrItemDao.findById(grrItemDto.getId());
        } else {
            grrItem = grrItemDao.findByGrrName(grrItemDto.getGrrName());
        }

        if (grrItem == null) {
            throw new ApplicationException(ExceptionMessages.ERR_15007, ResourceBundleUtils.getString(ExceptionMessages.EXCEPTION_GLOBAL_OBJECT_INVALID));
        }
        grrItemDto.setId(grrItem.getId());
        BeanUtils.copyProperties(grrItemDto, grrItem);
        grrItemDao.updateGrrItem(grrItem);
    }

    @Override
    public void deleteGrrItem(Long id) {
        if (id == null) {
            throw new ApplicationException(ExceptionMessages.EXCEPTION_PARAMETER_INPUT_INVALID);
        }
        GrrItem grrItem = grrItemDao.findById(id);
        if (grrItem == null) {
            throw new ApplicationException(ExceptionMessages.ERR_15007, ResourceBundleUtils.getString(ExceptionMessages.EXCEPTION_GLOBAL_OBJECT_INVALID));
        }
        grrItemDao.deleteGrrItem(id);
    }

    @Override
    public GrrItemDto findById(Long id) {
        if (id == null) {
            throw new ApplicationException(ExceptionMessages.EXCEPTION_PARAMETER_INPUT_INVALID);
        }
        GrrItem grrItem = grrItemDao.findById(id);
        if (grrItem == null) {
            throw new ApplicationException(ExceptionMessages.ERR_15007, ResourceBundleUtils.getString(ExceptionMessages.EXCEPTION_GLOBAL_OBJECT_INVALID));
        }
        GrrItemDto grrItemDto = new GrrItemDto();
        BeanUtils.copyProperties(grrItem, grrItemDto);

        return grrItemDto;
    }

    @Override
    public GrrItemDto findGrrItemByGrrName(String grrName) {
        if (StringUtils.isBlank(grrName)) {
            throw new ApplicationException(ExceptionMessages.ERR_14001, ResourceBundleUtils.getString(ExceptionMessages.EXCEPTION_CONFIG_PARAMETER_INVALID));
        }
        GrrItem grrItem = grrItemDao.findByGrrName(grrName);
        if (grrItem == null) {
            throw new ApplicationException(ExceptionMessages.ERR_15007, ResourceBundleUtils.getString(ExceptionMessages.EXCEPTION_GLOBAL_OBJECT_INVALID));
        }
        GrrItemDto grrItemDto = new GrrItemDto();
        BeanUtils.copyProperties(grrItem, grrItemDto);
        return grrItemDto;
    }

    @Override
    public void createSpcConfig(SpcConfigDto spcConfigDto) {
        if (spcConfigDto == null) {
            throw new ApplicationException(ExceptionMessages.ERR_14001, ResourceBundleUtils.getString(ExceptionMessages.EXCEPTION_CONFIG_PARAMETER_INVALID));
        }

        SpcConfig spcConfig = new SpcConfig();
        BeanUtils.copyProperties(spcConfigDto, spcConfig);
        spcConfigDao.createSpcConfig(spcConfig);
    }

    @Override
    public void updateSpcConfig(SpcConfigDto spcConfigDto) {
        if (spcConfigDto == null || spcConfigDto.getId() == null) {
            throw new ApplicationException(ExceptionMessages.ERR_14001, ResourceBundleUtils.getString(ExceptionMessages.EXCEPTION_CONFIG_PARAMETER_INVALID));
        }
        SpcConfig spcConfig = spcConfigDao.findById(spcConfigDto.getId());
        if (spcConfig == null) {
            throw new ApplicationException(ExceptionMessages.ERR_15007, ResourceBundleUtils.getString(ExceptionMessages.EXCEPTION_GLOBAL_OBJECT_INVALID));
        }
        spcConfigDto.setId(spcConfig.getId());
        BeanUtils.copyProperties(spcConfigDto, spcConfig);
        spcConfigDao.updateSpcConfig(spcConfig);
    }

    @Override
    public void updateMultiSpcConfig(List<SpcConfigDto> multiSpcConfig) {
        if (multiSpcConfig == null || multiSpcConfig.size() == 0) {
            throw new ApplicationException(ExceptionMessages.ERR_14001, ResourceBundleUtils.getString(ExceptionMessages.EXCEPTION_CONFIG_PARAMETER_INVALID));
        }

        for (SpcConfigDto spcConfigDto : multiSpcConfig) {
            updateSpcConfig(spcConfigDto);
        }
    }

    @Override
    public List<SpcConfigDto> findSpcConfigs() {
        List<SpcConfig> spcConfigs = spcConfigDao.findSpcConfigs();
        List<SpcConfigDto> spcConfigDtos = Lists.newArrayList();
        if (spcConfigs != null && !spcConfigs.isEmpty()) {
            for (SpcConfig spcConfig : spcConfigs) {
                SpcConfigDto spcConfigDto = new SpcConfigDto();
                BeanUtils.copyProperties(spcConfig, spcConfigDto);
                spcConfigDtos.add(spcConfigDto);
            }
        }
        return spcConfigDtos;
    }

    @Override
    public SpcConfigDto findSpcConfigById(Long id) {
        SpcConfig spcConfig = spcConfigDao.findSpcConfigById(id);
        SpcConfigDto spcConfigDto = new SpcConfigDto();
        BeanUtils.copyProperties(spcConfig, spcConfigDto);
        return spcConfigDto;
    }

    @Override
    public List<Integer> findSpcAndGrrDigit() {
        List<Integer> result = Lists.newArrayList();
        List<SpcConfig> spcConfigs = spcConfigDao.findSpcConfigs();

        for (SpcConfig config : spcConfigs) {
            if (config.getConfigType().equals(AppConstant.SPC_CONFIG_DIGIT)) {
                result.add(Integer.valueOf(config.getValue()));
                break;
            }
        }

        GrrConfig grrConfig = grrConfigDao.findGrrConfig();
        result.add(grrConfig.getDigit());

        return result;
    }

}
